package com.googlecode.dgwt.client.dojo.data.model;

import java.util.Map.Entry;

import com.googlecode.dgwt.client.dojo.Dojo;

/**
 * @author wellsantos@wellsantos.com
 * @since 0.01
 */
public class KeyValueModel<Key,Value> extends StoreModelBase<Entry<Key,Value>, KeyValueColumn<Key, Value>>{

    public static final int KEY_COLUMN_INDEX = 0;
    public static final int VALUE_COLUMN_INDEX = 1;
    
    
    public KeyValueModel(Class<Key> keyType, Class<Value> valueType) {
        super();
        getColumns().get(KEY_COLUMN_INDEX).setColumnType(keyType);
        getColumns().get(VALUE_COLUMN_INDEX).setColumnType(valueType);
    }

    @Override
    protected ColumnList createColumnList(int initialCapacity) {
        return new KeyValueColumnList(); 
    }

    @Override
    public Entry<Key, Value> createItem() {
        return new KeyValueItem<Key, Value>();
    }
    
    public Entry<Key, Value> createItem(Key key, Value value) {
        return new KeyValueItem<Key, Value>(key, value);
    }
    
    public static class KeyValueItem<Key, Value> implements KeyValueEntry<Key, Value>{

        private Key key;
        private Value value;
        
        public KeyValueItem() {
        }
        
        public KeyValueItem(Key key, Value value) {
            this.key = key;
            this.value = value;
        }

        public KeyValueItem(Entry<? extends Key, ? extends Value> entry) {
            this.key = entry.getKey();
            this.value = entry.getValue();
        }

        public Key setKey(Key key) {
            Key oldKey = key;
            this.key = key;
            return oldKey;
        }
        
        public Key getKey() {
            return key;
        }

        public Value setValue(Value value) {
            Value oldValue = this.value;
            this.value = value;
            return oldValue;
        }

        public Value getValue() {
            return value;
        }

    }
    
    protected class KeyValueColumnList extends ColumnList {

        protected boolean loading = true;
        
        protected KeyValueColumnList() {
            super(2);
            add(new KeyValueColumn<Key, Value>());
            add(new KeyValueColumn<Key, Value>());
            loading = false;
        }

        @Override
        protected void internalAdd(int index, KeyValueColumn<Key, Value> item) {
            if (!loading){
                throw new UnsupportedOperationException();
            }
            super.internalAdd(index, item);
        }

        @Override
        protected void internalRemove(int index, KeyValueColumn<Key, Value> item) {
            throw new UnsupportedOperationException(
                    Dojo.reflect.getSimpleName(KeyValueModel.class) + 
                    ": only two columns is allowed and required: one for Key and another for Value.");
        }
    };
}
